import { CrudService } from '@nest-crud/crud';
import {
  ControllerMethods,
  ControllerMethodType,
  CrudControllerProp,
} from '../../interfaces/crud-controller.interface';

type TupleToUnion<T extends unknown[]> = T[number];
type mergeController<
  T,
  ExcludeMethods extends ControllerMethods[],
  Method extends keyof ControllerMethodType<T>
> = Method extends TupleToUnion<ExcludeMethods> ? unknown : ControllerMethodType<T>[Method];

export type getController<T, ExcludeMethods extends ControllerMethods[]> = CrudControllerProp<T> &
  mergeController<T, ExcludeMethods, 'createManyBase'> &
  mergeController<T, ExcludeMethods, 'createOneBase'> &
  mergeController<T, ExcludeMethods, 'deleteOneBase'> &
  mergeController<T, ExcludeMethods, 'getManyBase'> &
  mergeController<T, ExcludeMethods, 'getOneBase'> &
  mergeController<T, ExcludeMethods, 'recoverOneBase'> &
  mergeController<T, ExcludeMethods, 'replaceOneBase'> &
  mergeController<T, ExcludeMethods, 'updateOneBase'>;
export type CurdControllerCtor<Entity, ExcludeFn extends ControllerMethods[] = []> = new (
  service: CrudService<Entity>
) => getController<Entity, ExcludeFn>;
